/*
 * Copyright (C) 2010 The Android Open Source Project 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */

package org.lhlzi.ithink.dao;

import java.util.List;

import org.lhlzi.ithink.EventListBuilder;
import org.lhlzi.ithink.IphoneCallLogScreen;
import org.lhlzi.ithink.model.IRecentContactChangedListener;
import org.lhlzi.ithink.model.RecentContact;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;

public abstract class ContentResolverTemplate implements EventObserver {

	private static final String TAG = "RW:ContentResolverTplt";

	protected String[] projection;

	protected String sortOrder;

	protected Context context;

	private ContentResolver contentResolver;

	protected abstract long extractEvent(EventListBuilder builder, Cursor cursor, IRecentContactChangedListener listen);

	protected abstract int getTargetType();

	// as a getter because we want to override it
	protected abstract Uri getContentUri();

	@Override
	public List<RecentContact> update(List<RecentContact> recentContacts,
			Intent intent, Context context, IRecentContactChangedListener listen) {

		if (intent != null) {
			Log.d(TAG, "Received broadcasted " + intent.getAction());
		}

		// Note: Not concurrent-friendly!

		// Note: Make sure no unnecessary ArrayLists created in all those
		// params/returns.

		this.context = context;
		this.contentResolver = context.getContentResolver();

		return fetchEvents(recentContacts, intent, listen);
	}

	/**
	 * Only one-time use as the template's content resolver is set to null
	 * afterwards. (this is to avoid any long-lived reference / leaks)
	 * 
	 * Uses the specific Dao extractEvent to traverse (pattern?) the cursor.
	 * 
	 */
	protected List<RecentContact> fetchEvents(List<RecentContact> recentContacts, Intent intent, 
			IRecentContactChangedListener listen) {
		// The builder is useful in order for the business logic to be stored
		// elsewhere.

		EventListBuilder builder = new EventListBuilder(recentContacts);

		Cursor cursor = null;

		try {

			// Do not use managedQuery() because we will unload it ourselves

			cursor = contentResolver.query(getContentUri(), projection,
					getQuery(), null, sortOrder);

			if (cursor.moveToFirst()) {
				if (intent != null && intent.getAction().equals(IphoneCallLogScreen.ACTION)) {
					
					extractEvent(builder, cursor, listen);
					
				} else {
				
					while (!cursor.isAfterLast()) {
	
						// "extract" actually adds to the list
	
	//					long eventDate = 
						extractEvent(builder, cursor, listen);
	
						// At this point, the event was already added. Just check if
						// next event should be fetched; or do we have enough events
						// already.
	
	//					if (builder.isFull(eventDate, getTargetType())) {
	//						break;
	//					}
	
						cursor.moveToNext();
					}
				}
			}

		} catch (Exception e) {
			// Let exception escape, so we have a functioning widget
			Log.e(TAG, "Exception while querying " + getContentUri(), e);
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}

		// Avoid memory leaks
		// http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/

		contentResolver = null;
		context = null;

		return builder.build();
	}

	protected String getQuery() {
		return null;
	}

}
